package com.ncmmall.application.business.distribution;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import com.ncmmall.application.business.order.wechat.WechatRefundRequest;
import com.feijin.commons.lang.ArithUtils;
import com.feijin.commons.lang.Requires;
import com.ncmmall.domain.business.distribution.Distributor;
import com.ncmmall.domain.business.distribution.DistributorRepository;
import com.ncmmall.domain.business.distribution.DistributorWithdrawPayRecord;
import com.ncmmall.domain.business.distribution.DistributorWithdrawPayRecordRepository;
import com.ncmmall.domain.business.distribution.DistributorWithdrawRecord;
import com.ncmmall.domain.business.distribution.DistributorWithdrawRecordRepository;
import com.ncmmall.domain.security.user.WebUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 分销商提现管理
 */
@Service
@Transactional
@Slf4j
public class DistributorWithdrawRecordApplication {

    @Autowired
    private DistributorWithdrawRecordRepository distributorWithdrawRecordRepository;

    @Autowired
    private DistributorRepository distributorRepository;

    @Autowired
    private DistributorWithdrawPayRecordRepository distributorWithdrawPayRecordRepository;

    /**
     * 创建提现记录
     *
     * @param record 记录
     */
    public void create(DistributorWithdrawRecord record) {

        record.setCreateTime(new Timestamp(System.currentTimeMillis()));
        record.setStatus(1);
        distributorWithdrawRecordRepository.save(record);

        Distributor distributor = record.getDistributor();
        distributor.setBalance(ArithUtils.roundHalfUp(distributor.getBalance() - record.getWithDrawMoney(), 2));
        distributorRepository.save(distributor);
    }

    /**
     * 提现审核
     *
     * @param record 申请记录
     * @param status 审核状态 2、通过 3、不通过
     * @param note   审核备注
     */
    public void check(DistributorWithdrawRecord record, int status, String note) {
        record.setStatus(status);
        record.setNote(note);
        record.setCheckTime(new Timestamp(System.currentTimeMillis()));
        distributorWithdrawRecordRepository.save(record);

        if (record.getStatus() == 3) {
            Distributor distributor = record.getDistributor();
            distributor.setBalance(ArithUtils.add(distributor.getBalance(), record.getWithDrawMoney()));
            distributorRepository.save(distributor);
        }
    }

    /**
     * 微信提现
     *
     * @param record   提现记录
     * @param status   审核状态 3、拒绝 4、支付
     * @param note     拒绝备注
     * @param operator 操作人
     */
    public void checkWechatWithdraw(DistributorWithdrawRecord record, int status, String note, WebUser operator) {

        Distributor distributor = record.getDistributor();
        WebUser user = distributor.getUser();
        Requires.hasLength(user.getOpenId(), "无法获取用户openId");

        double totalMoney = record.getWithDrawMoney();
        record.setOperator(operator);
        record.setStatus(status);
        if (status == 3) {
            record.setNote(note);
        }

        if (status == 3) {
            distributor.setBalance(NumberUtil.roundDown(NumberUtil.add(distributor.getBalance(), totalMoney), 2).doubleValue());
            distributorRepository.save(distributor);
            distributorWithdrawRecordRepository.save(record);
            return;
        }

        //生成支付凭证
        DistributorWithdrawPayRecord payRecord = new DistributorWithdrawPayRecord();
        payRecord.setCreateTime(new Timestamp(System.currentTimeMillis()));
        payRecord.setPayMoney(totalMoney);
        payRecord.setRecordNo(DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN) + RandomUtil.randomNumbers(6));
        payRecord.setDistributor(distributor);
        payRecord.setStatus(1);
        payRecord.setPayType(1);
        payRecord.setPartnerTradeNo(DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN) + RandomUtil.randomNumbers(12));

        //微信转账
        Map<String, String> reqData = new HashMap<>();
        reqData.put("partner_trade_no", payRecord.getPartnerTradeNo());
        reqData.put("openid", user.getOpenId());
        reqData.put("check_name", "NO_CHECK");
        reqData.put("amount", String.valueOf((int) ArithUtils.mul(totalMoney, 100)));
        reqData.put("desc", "分销提现");

        Map<String, String> map = new WechatRefundRequest().mmpaymkttransfers(reqData);
        log.info("微信提现信息：{}", map);

        if (map.get("flag").equals("true")) {
            payRecord.setStatus(2);
            payRecord.setPayTime(new Timestamp(System.currentTimeMillis()));
            payRecord.setPaymentNo(map.get("payment_no"));
        } else {
            payRecord.setStatus(3);
            payRecord.setNote(map.get("message"));
        }
        distributorWithdrawPayRecordRepository.save(payRecord);
    }

    /**
     * 银行卡提现
     *
     * @param record   提现记录
     * @param status   审核状态 3、拒绝 4、支付
     * @param note     拒绝备注
     * @param operator 操作人
     */
    public void checkBankCardWithdraw(DistributorWithdrawRecord record, int status, String note, String image, WebUser operator) {

        double totalMoney = record.getWithDrawMoney();
        record.setStatus(status);
        record.setOperator(operator);
        if (status == 3) {
            record.setNote(note);
        }

        Distributor distributor = record.getDistributor();
        //拒绝
        if (status == 3) {
            //还原余额, 保存记录
            distributor.setBalance(NumberUtil.roundDown(NumberUtil.add(distributor.getBalance(), totalMoney), 2).doubleValue());
            distributorRepository.save(distributor);
            distributorWithdrawRecordRepository.save(record);
            return;
        }

        //生成支付凭证
        DistributorWithdrawPayRecord payRecord = new DistributorWithdrawPayRecord();
        payRecord.setCreateTime(new Timestamp(System.currentTimeMillis()));
        payRecord.setPayMoney(totalMoney);
        payRecord.setRecordNo(DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN) + RandomStringUtils.randomNumeric(6));
        payRecord.setDistributor(distributor);
        payRecord.setStatus(2);
        payRecord.setPayType(2);

        payRecord.setBankCardNo(record.getBankCardNo());
        payRecord.setBankName(record.getBankName());
        payRecord.setBankSubBranch(record.getBankSubBranch());
        payRecord.setImage(image);
        distributorWithdrawPayRecordRepository.save(payRecord);

        record.setRecord(payRecord);
        distributorWithdrawRecordRepository.save(record);
    }
}
